﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using Caliburn.Micro.BikeWizard.Views;
using Caliburn.Micro.BikeWizard.Data;

namespace Caliburn.Micro.BikeWizard.Utils
{
    /// <summary>
    /// Helps with the conversion of Option objects to OptionViewModel objects
    /// </summary>
    public class OptionViewModelHelper
    {
        /// <summary>
        /// Convert a collecton of Option objects to a collecton of OptionViewModel objects
        /// and calls some delegates if certain contains are met
        /// </summary>
        /// <typeparam name="TOption">The derivative of Option to convert</typeparam>
        /// <param name="options">The collection of Option objects to convert</param>
        /// <param name="optionViewModelListCreated">Delegate to call when all Option objects have been converted</param>
        /// <param name="setDefaultOption">Delegate to call whe op Option object is encountered that has it's IsDefault property set to true</param>
        /// <param name="optionIsSelectedPropertyChanged">Delegate to call when the IsSelected property of a created OptionViewModel object is changed</param>
        /// <returns></returns>
        public static IResult CreateOptionViewModelList<TOption>(
            IEnumerable<TOption> options,
            Action<IEnumerable<OptionViewModel<TOption>>> optionViewModelListCreated,
            Action<OptionViewModel<TOption>> setDefaultOption,
            Action<OptionViewModel<TOption>> optionIsSelectedPropertyChanged) where TOption : Option
        {
            return new ActionResult(
                (actionResult) =>
                {
                    var optionViewModels = new List<OptionViewModel<TOption>>();
                    options.ToList().ForEach(
                        (option) =>
                        {
                            var optionViewModel = new OptionViewModel<TOption>(option.DisplayName, option, option.SortOrder) { IsSelected = option.IsDefault };
                            optionViewModels.Add(optionViewModel);

                            if (option.IsDefault)
                            {
                                setDefaultOption(optionViewModel);
                            }
                        });

                    optionViewModels.Apply(
                        (optionViewModel) =>
                        {
                            optionViewModel.PropertyChanged +=
                                (sender, e) =>
                                {
                                    if (e.PropertyName == "IsSelected")
                                    {
                                        var option = sender as OptionViewModel<TOption>;
                                        optionIsSelectedPropertyChanged(option);
                                    }
                                };
                        });

                    optionViewModels.Sort();
                    optionViewModelListCreated(optionViewModels);

                    actionResult.SetComplete(null);
                });
        }
    }
}
